# Visualización de datos geográficos con leaflet
# Configuración
!pip install folium==0.12.0
# Visualization de mapas con folium (leaflet)
import folium
import json
Comenzamos creando un mapa muy simple con un marcador en las coordenadas [40.4066853,-3.7091432].
myloc = [40.4066853,-3.7091432]
m = folium.Map(location = myloc, zoom_start=15)
folium.Marker(myloc, popup='Estás aquí').add_to(m)
m
m = folium.Map(location = myloc, zoom_start=15)
folium.Marker(myloc, popup='<p>Tu IP dice <h4>estás aquí<h4/><p/>').add_to(m)
m
Podemos añadir tantos marcadores como necesitemos y cambiar otras propiedades.
folium.Marker(location=[40.42,-3.72], tooltip='pero en realidad estás aquí').add_to(m)
m
Ahora descargaremos el mapa de países de europa en formato GeoJson. Podemos configurar nuestro propio mapa en este sitio: https://geojson-maps.ash.ms/
!wget 'https://raw.githubusercontent.com/johan/world.geo.json/master/countries.geo.json'
--2021-02-13 10:18:52-- https://raw.githubusercontent.com/johan/world.geo.json/master/countries.geo.json
Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.108.133, 185.199.111.133, 185.199.109.133, ...
Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.108.133|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 256950 (251K) [text/plain]
Saving to: 'countries.geo.json.1'
countries.geo.json. 100%[===================>] 250.93K --.-KB/s in 0.03s
2021-02-13 10:18:52 (7.27 MB/s) - 'countries.geo.json.1' saved [256950/256950]
m = folium.Map()
folium.GeoJson('custom.geo.json').add_to(m)
m
Podemos seguir configurando nuestro mapa.
m = folium.Map()
folium.GeoJson('custom.geo.json',
style_function = lambda x: {'fillOpacity': '0', 'weight': '1'}).add_to(m)
m
Para comprender la estructura de custom.geo.json vamos a traerlo a python.
countries = json.load(open('custom.geo.json'))
countries.keys()
dict_keys(['type', 'features'])
countries['type']
'FeatureCollection'
# countries['features'][0]
Vemos que el campo properties tiene mucha información relacionada con el país, y podemos añadir nuestra propia información. Vamos a utilizar esta información para mostrar un tooltip sobre cada país. Para mostrar colores podemos escoger un tema aquí (opens new window).
m = folium.Map()
colors = ['#8c510a', '#bf812d', '#dfc27d', '#f6e8c3', '#f5f5f5', '#c7eae5', '#80cdc1', '#35978f', '#01665e']
folium.GeoJson('custom.geo.json',
style_function = lambda x: {
'fillColor': colors[int(x['properties']['mapcolor9'])-1],
'fillOpacity': '0.8',
'weight': '1'},
tooltip = folium.GeoJsonTooltip(
fields = ['admin', 'formal_en', 'income_grp']
)
).add_to(m)
m
También podemos asignar los colores en función de una variable continua, por ejemplo, gdp_md_est. Para esto, primeramente vamos a explorar el rango de esta variable, en un data frame de pandas.
import pandas as pd
pdf = None
for i in range(len(countries['features'])):
pdf = pd.DataFrame(countries['features'][i]['properties'], index=[i]).append(pdf)
# pdf
# pdf[['admin', 'gdp_md_est']].sort_values('gdp_md_est')
Creamos una escala lineal desde 0 hasta 3
import branca.colormap as cmp
linear = cmp.LinearColormap(
['red', 'yellow', 'green'],
vmin=0, vmax=3,
caption='GDP (millones)' #Caption for Color scale or Legend
)
linear
m = folium.Map()
folium.GeoJson('custom.geo.json',
style_function = lambda x: {
'fillColor': linear(x['properties']['gdp_md_est']/1e+6),
'fillOpacity': '0.8',
'weight': '1'},
tooltip = folium.GeoJsonTooltip(
fields = ['admin', 'formal_en', 'income_grp']
)
).add_to(m)
linear.add_to(m)
m
Ahora vamos a escalar por el tamaño de la población.
pdf.loc[:,'gdp_per_capita'] = pdf.gdp_md_est/pdf.pop_est
pdf[['admin', 'gdp_md_est', 'pop_est', 'gdp_per_capita']].sort_values('gdp_per_capita')
| admin | gdp_md_est | pop_est | gdp_per_capita | |
|---|---|---|---|---|
| 35 | Moldova | 10670.0 | 4320748 | 0.002469 |
| 25 | Kosovo | 5352.0 | 1804838 | 0.002965 |
| 3 | Albania | 21810.0 | 3639453 | 0.005993 |
| 7 | Bosnia and Herzegovina | 29700.0 | 4613414 | 0.006438 |
| 49 | Ukraine | 339800.0 | 45700395 | 0.007435 |
| 33 | Macedonia | 18780.0 | 2066718 | 0.009087 |
| 38 | Montenegro | 6816.0 | 672180 | 0.010140 |
| 45 | Republic of Serbia | 80340.0 | 7379339 | 0.010887 |
| 8 | Belarus | 114100.0 | 9648533 | 0.011826 |
| 41 | Romania | 271400.0 | 22215421 | 0.012217 |
| 0 | Bulgaria | 93750.0 | 7204687 | 0.013012 |
| 36 | Russia | 2266000.0 | 140041247 | 0.016181 |
| 39 | Poland | 667900.0 | 38482919 | 0.017356 |
| 31 | Latvia | 38860.0 | 2231503 | 0.017414 |
| 29 | Lithuania | 63330.0 | 3555179 | 0.017813 |
| 20 | Croatia | 82390.0 | 4489409 | 0.018352 |
| 43 | Portugal | 208627.0 | 10707924 | 0.019483 |
| 22 | Hungary | 196600.0 | 9905596 | 0.019847 |
| 12 | Faroe Islands | 1000.0 | 48856 | 0.020468 |
| 13 | Estonia | 27410.0 | 1299371 | 0.021095 |
| 40 | Slovakia | 119500.0 | 5463046 | 0.021874 |
| 34 | Malta | 9962.0 | 405165 | 0.024588 |
| 5 | Czech Republic | 265200.0 | 10211904 | 0.025970 |
| 46 | Slovenia | 59340.0 | 2005692 | 0.029586 |
| 32 | Monaco | 976.3 | 32965 | 0.029616 |
| 28 | Italy | 1823000.0 | 58126212 | 0.031363 |
| 18 | United Kingdom | 1977704.0 | 62262000 | 0.031764 |
| 19 | Greece | 343000.0 | 10737428 | 0.031944 |
| 17 | France | 2128000.0 | 64057792 | 0.033220 |
| 16 | Spain | 1403000.0 | 40525002 | 0.034621 |
| 10 | Germany | 2918000.0 | 82329758 | 0.035443 |
| 23 | Isle of Man | 2719.0 | 76512 | 0.035537 |
| 15 | Finland | 193500.0 | 5250275 | 0.036855 |
| 11 | Denmark | 203600.0 | 5500510 | 0.037015 |
| 4 | Belgium | 389300.0 | 10414336 | 0.037381 |
| 47 | Sweden | 344300.0 | 9059651 | 0.038004 |
| 14 | Guernsey | 2742.0 | 68633 | 0.039952 |
| 1 | Austria | 329500.0 | 8210281 | 0.040133 |
| 37 | Netherlands | 672000.0 | 16715999 | 0.040201 |
| 27 | Iceland | 12710.0 | 306694 | 0.041442 |
| 9 | Switzerland | 316700.0 | 7604467 | 0.041647 |
| 2 | Andorra | 3660.0 | 83888 | 0.043630 |
| 21 | Ireland | 188400.0 | 4203200 | 0.044823 |
| 44 | San Marino | 1662.0 | 30324 | 0.054808 |
| 26 | Jersey | 5100.0 | 91626 | 0.055661 |
| 6 | Aland | 1563.0 | 27153 | 0.057563 |
| 42 | Norway | 276400.0 | 4676305 | 0.059106 |
| 30 | Luxembourg | 39370.0 | 491775 | 0.080057 |
| 24 | Liechtenstein | 4160.0 | 34761 | 0.119674 |
| 48 | Vatican | 355.0 | 832 | 0.426683 |
for i in range(len(countries['features'])):
gdp = countries['features'][i]['properties']['gdp_md_est']
pop = countries['features'][i]['properties']['pop_est']
countries['features'][i]['properties']['gdp_per_capita'] = gdp/pop
# countries['features'][0]['properties']
linear = cmp.LinearColormap(
['red', 'yellow', 'green'],
vmin=0, vmax=0.1,
caption='GDP (scaled)' #Caption for Color scale or Legend
)
m = folium.Map()
folium.GeoJson(countries,
style_function = lambda x: {
'fillColor': linear(x['properties']['gdp_per_capita']),
'fillOpacity': '0.8',
'weight': '1'},
tooltip = folium.GeoJsonTooltip(
fields = ['admin', 'formal_en', 'income_grp', 'gdp_per_capita']
)
).add_to(m)
linear.add_to(m)
m
# Ejercicio
La tabla consumption.csv contiene la información del consumo eléctrico de varios países europeos. ¿Serías capaz de mostrar esta información en un mapa sobre los países, con una escala de colores que haga referencia al consumo anual de cada país?